import {
  Controller,
  Get,
  Query,
  Post,
  Body,
  Put,
  Param,
  Delete,
  Req,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { Request } from 'express';
import { CreatePermissionDto as CreateDto } from './dtos/create.dto';
import { QueryPermissionDto as QueryDto } from './dtos/query.dto';
import { UpdatePermissionDto as UpdateDto } from './dtos/update.dto';
import { Permissions } from 'src/decorators/permissions.decorator';
import { PermissionService } from './permission.service';
import { Op } from 'sequelize';
import type { Order } from 'sequelize';
import { ApiTags, IntersectionType } from '@nestjs/swagger';
import { ExtraModelDto } from 'src/dtos/extra-model.dto';
import {
  ApiCommonDataBooleanResponse,
  ApiCommonDataResponse,
} from 'src/decorators/api-common-data-response.decorator';
import { ApiPaginatedResponse } from 'src/decorators/api-paginated-response.decorator';

@ApiTags('permission')
@Controller('permission')
export class PermissionController {
  constructor(private permissionService: PermissionService) {}

  @Permissions('permission.create')
  @HttpCode(HttpStatus.OK)
  @Post()
  @ApiCommonDataResponse(IntersectionType(CreateDto, ExtraModelDto))
  create(@Req() request: Request, @Body() createDto: CreateDto) {
    return this.permissionService.create(createDto);
  }

  @Permissions('permission.findAll')
  @HttpCode(HttpStatus.OK)
  @Get()
  @ApiPaginatedResponse(CreateDto)
  findAll(@Req() request: Request, @Query() query: QueryDto) {
    const search = ['search_code', 'search_description'].filter(
      (key) => query[key],
    );
    const where = {};
    if (search.length) {
      where[Op.or] = search.map((key) => ({
        [key.slice(7)]: {
          [Op.substring]: query[key],
        },
      }));
    }
    const sort = ['sort_created_at'];
    const order = sort.map((key) => [
      key.slice(5),
      query[key] === 'desc' ? 'desc' : 'asc',
    ]); // [["created_at", "desc"]]
    return this.permissionService.findAll(
      +query.limit,
      +query.page,
      where,
      order as Order,
    );
  }

  @Permissions('permission.findOne')
  @HttpCode(HttpStatus.OK)
  @Get(':id')
  @ApiCommonDataResponse(IntersectionType(CreateDto, ExtraModelDto))
  findOne(@Req() request: Request, @Param('id') id: string) {
    return this.permissionService.findByPk(id);
  }

  @Permissions('permission.update')
  @HttpCode(HttpStatus.OK)
  @Put(':id')
  @ApiCommonDataResponse(IntersectionType(UpdateDto, ExtraModelDto))
  update(
    @Req() request: Request,
    @Param('id') id: string,
    @Body() updateDto: UpdateDto,
  ) {
    return this.permissionService.update(id, updateDto);
  }

  @Permissions('permission.remove')
  @HttpCode(HttpStatus.OK)
  @Delete(':id')
  @ApiCommonDataBooleanResponse()
  remove(@Req() request: Request, @Param('id') id: string) {
    return this.permissionService.remove(id);
  }

  @Permissions('permission.removeBatch')
  @HttpCode(HttpStatus.OK)
  @Delete('batch/:ids')
  @ApiCommonDataBooleanResponse()
  removeBatch(@Req() request: Request, @Param('ids') ids: string) {
    return this.permissionService.removeBatch(ids.split(','));
  }
}
